package com.kaibes.module.log;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.kaibes.web.filter.BasicInterceptor;
import com.kaibes.web.util.IpUtils;

@Component
public class ApiLogFilter implements BasicInterceptor {

    public final static String REQUEST = "request", RESPONSE = "response", REQUEST_TIME = "request_time",
            RESPONSE_TIME = "response_time", REQUEST_URL = "request_url", REQUEST_HEADER = "request_header";

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private ApiLogService apiLogService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        return true;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    	String requestUrl = (String) request.getAttribute(ApiLogFilter.REQUEST_URL);
        if (requestUrl == null) {
            return;
        }
        
        ApiLog log = new ApiLog();
        log.setIp(IpUtils.getIpAddr(request));
        log.setUserId((Integer) request.getAttribute("userId"));
        log.setMethod(request.getMethod());
        
        String read = (String) request.getAttribute(ApiLogFilter.REQUEST);
        HashMap<String, String> requestHeader = (HashMap<String, String>) request.getAttribute(ApiLogFilter.REQUEST_HEADER);
        LocalDateTime requestTime = (LocalDateTime) request.getAttribute(ApiLogFilter.REQUEST_TIME);
        if (read != null) {
            log.setRequest(read);
        }
        log.setUrl(requestUrl);
        log.setRequestHeader(objectMapper.writeValueAsString(requestHeader));
        log.setRequestTime(requestTime);
        
        Object write = request.getAttribute(ApiLogFilter.RESPONSE);
        if (write != null) {
            log.setResponse(objectMapper.writeValueAsString(write));
        }
        log.setStatusCode(response.getStatus());
        Collection<String> names = response.getHeaderNames();
        HashMap<String, String> responseHeader = new HashMap<>();
        for (String key : names) {
            String value = response.getHeader(key);
            responseHeader.put(key, value);
        }
        log.setResponseHeader(objectMapper.writeValueAsString(responseHeader));
        
        log.setResponseTime(LocalDateTime.now());
        apiLogService.save(log);
    }
}
